﻿using System;
using System.Collections.Generic;

namespace Tanmia.Basis.Data
{
    /// <summary>
    /// Represent (Create, Update, Retrive, and Delete) capabilities which could be executed on the database.
    /// All CRUD operation manipulated by BaseBusinessObject dervied classes (Core).
    /// </summary>
    /// <typeparam name="TCore">Any Core class which dervied from BaseBusinessObject, which we are going to deal with its Data Repositor.</typeparam>
    public interface IRepository<TCore>
    {
        /// <summary>
        /// Saves business object in the database.
        /// Returns the object after populate the calculated values from the database back.
        /// </summary>
        /// <param name="entity">BusinessObject to save.</param>
        /// <returns>Persisted object in the database.</returns>
        /// <exception cref="ConstraintViolationException">which is raised from the Database according to the constraint violation value.</exception>
        TCore Save(TCore entity);

        /// <summary>
        /// يقوم بتعديل السطر المقابل للكائن في قاعدة البيانات, وإعادة الكائن بعد أن تم تعبئته من قاعدة البيانات من جديد
        /// </summary>
        /// <param name="entity">الكائن الذي نريد تعديله</param>
        /// <returns>الكائن المحفوظ في قاعدة البيانات</returns>
        TCore Update(TCore entity);

        /// <summary>
        /// Delete business object from the database.
        /// </summary>
        /// <param name="entity">Business object to delete.</param>
        void Delete(TCore entity);

        /// <summary>
        /// Retrive identified business object from the database.
        /// </summary>
        /// <param name="entityID">Business object identity.</param>
        /// <returns>Retrived business object from the database.</returns>
        TCore Get(int entityID);

        /// <summary>
        /// يقوم بإعادة كافة الكائنات المحفوظة في قاعدة البيانات
        /// Retrive all business object from the database.
        /// </summary>
        /// <returns>List of all business objects.</returns>
        /// <remarks>
        /// It is NOT recommanded to use this method cause the list that will be returned has a larg size.
        /// </remarks>
        IList<TCore> Gets();

        /// <summary>
        /// يقوم بتطبيق المقايس الممررة له على البيانات الموجودة في قاعدة البيانات ويعيد النتيجة
        /// </summary>
        /// <param name="propertyValuepairs">مجموعة من أسماء الخصائص والقيم التي نريد تطبيقها على قاعدة البيانات</param>
        /// <returns>قائمة بكافة الكائنات التي تحقق المقياس</returns>
        IList<TCore> Search(Dictionary<string, object> propertyValuepairs);

        /// <summary>
        /// Retrive a list of all business object that satisfy a given specification.
        /// </summary>
        /// <param name="specs">Specification object which have the filter criteria.</param>
        /// <returns>List of filtered business objects.</returns>
        IList<TCore> Gets(Specification<TCore> specs);

        /// <summary>
        /// Retrive a list of all business object that satisfy a give expression.
        /// </summary>
        /// <param name="satisfy">Filter expression to apply on the result of business objects.</param>
        /// <returns>List of filtered business objects.</returns>
        IList<TCore> Gets(System.Linq.Expressions.Expression<Func<TCore, bool>> satisfy);

        System.Linq.IQueryable<TCore> RepositoryItems { get; }
    }
}
